<?php

namespace App\Sock\Controller;

use App\Task\Broadcast;
use App\Utility\MTool;
use EasySwoole\Config;
use EasySwoole\Core\Component\Cache\Cache;
use EasySwoole\Core\Component\Di;
use EasySwoole\Core\Component\Spl\SplStream;
use EasySwoole\Core\Socket\AbstractInterface\WebSocketController;
use App\Sock\Logic\Game as GameLogic;
use EasySwoole\Core\Socket\Client\WebSocket;
use EasySwoole\Core\Socket\Common\CommandBean;
use EasySwoole\Core\Swoole\Task\TaskManager;
use EasySwoole\Core\Swoole\ServerManager;

class Game extends WebSocketController
{


    protected $db;

    public function __construct(WebSocket $client, CommandBean $request, SplStream $response)
    {
        $dbConf = Config::getInstance()->getConf('database');
        $this->db = Di::getInstance()->get("MYSQL");
        $this->db->setPrefix($dbConf['prefix']);
        parent::__construct($client, $request, $response);
    }

    public function login()
    {
        $param = $this->request()->getArgs();
        $client = $this->client();
        $data = $param['content'];
        $room_uid = $data['room_id'];
        $user_uuid = $data['user_uuid'];
        GameLogic::bindUser($user_uuid, $client->getFd());


        $user = GameLogic::selectRoomUserId($room_uid);
        // 获取

        if (!empty($user)) {
            if (count($user) > 6) {
                $this->response()->write(json_encode(['type' => 'close', 'event' => 'user_full', 'msg' => '客户端用户已满']));
                return false;
            }
            if (in_array($user_uuid, $user)) {
                $fd = GameLogic::getUserFd($user_uuid);
                GameLogic::recyclingFd($fd[0]);

                GameLogic::joinRoom($room_uid, $client->getFd(), $user_uuid);
                $user_list = GameLogic::selectRoomUserId($room_uid);


                $cols = ['user_uuid', 'username', 'id', 'user_nick', 'headimg'];
                $this->db->where('user_uuid', ['in' => $user_list]);
                $users = $this->db->get('user', null, $cols);
                foreach ($users as $item => $value) {
                    if ($value['user_uuid'] == $user_uuid) {
                        $own = $value;
                        break;
                    }
                }

                //获取最新回合信息
                $this->db->where('room_uuid', $room_uid);
                $this->db->where('year', date('Y'));
                $this->db->where('month', date('m'));
                $this->db->where('day', date('d'));
                $this->db->orderBy('round_id', 'desc');
                $res = $this->db->getOne('game_round');

                $data = ['type' => 'update_players', 'list' => $users];
                $return_data = [
                    'type' => 'init',
                    'list' => $users,
                    'is_login' => true,
                    'own_info' => $own,
                    'round_turn' => $res['round_turn'],
                    'last_lottery' => $this->getLastLotteryNumber($room_uid),
                ];

                $this->response()->write(json_encode($return_data));

                TaskManager::async(new Broadcast(['room_id' => $room_uid, 'payload' => json_encode($data)]));
            } else {
                GameLogic::joinRoom($room_uid, $client->getFd(), $user_uuid);
                $user_list = GameLogic::selectRoomUserId($room_uid);

                $cols = ['user_uuid', 'username', 'id', 'user_nick', 'headimg'];
                $this->db->where('user_uuid', ['in' => $user_list]);
                $users = $this->db->get('user', null, $cols);
                foreach ($users as $item => $value) {
                    if ($value['user_uuid'] == $user_uuid) {
                        $own = $value;
                        break;
                    }
                }

                //获取最新回合信息
                $this->db->where('room_uuid', $room_uid);
                $this->db->where('year', date('Y'));
                $this->db->where('month', date('m'));
                $this->db->where('day', date('d'));
                $this->db->orderBy('round_id', 'desc');
                $res = $this->db->getOne('game_round');

                $data = ['type' => 'update_players', 'list' => $users];
                $return_data = [
                    'type' => 'init',
                    'list' => $users,
                    'is_login' => true,
                    'own_info' => $own,
                    'round_turn' => $res['round_turn'],
                    'last_lottery' => $this->getLastLotteryNumber($room_uid),
                ];

                $this->response()->write(json_encode($return_data));

                TaskManager::async(new Broadcast(['room_id' => $room_uid, 'payload' => json_encode($data)]));
            }

        } else {
            GameLogic::joinRoom($room_uid, $client->getFd(), $user_uuid);
            $user_list = GameLogic::selectRoomUserId($room_uid);

            $cols = ['user_uuid,username,id,user_nick,headimg'];
            $this->db->where('user_uuid', ['in' => $user_list]);
            $users = $this->db->get('user', null, $cols);
            foreach ($users as $item => $value) {
                if ($value['user_uuid'] == $user_uuid) {
                    $own = $value;
                    break;
                }
            }
            //获取最新回合信息

            $data = ['type' => 'update_players', 'list' => $users];
            $return_data = ['type' => 'init', 'list' => $users, 'is_login' => true, 'last_lottery' => $this->getLastLotteryNumber($room_uid), 'own_info' => $own];
            $this->response()->write(json_encode($return_data));

            TaskManager::async(new Broadcast(['room_id' => $room_uid, 'payload' => json_encode($data)]));

        }

    }

    public function end_turn()
    {

//        TaskManager::async(new Broadcast(['payload' => json_encode(['type' => 'new_turn'])]));
    }

    public function draw_coin()
    {
        $args = $this->request()->getArgs();
        $param = $args['content'];

        // 获取 房间ID
        $room_uuid = GameLogic::getRoomId($this->client()->getFd());


        $from_uuid = GameLogic::getUserId($this->client()->getFd());

        // 获取 当前局数
        $info = $this->getCurrentRoundInfo();
        $round_uuid = $info['round_info']['round_circle'];

        $round_qishu = $info['round_period'] . $round_uuid;


        $this->db->where('round_turn', $round_qishu);
        $this->db->where('room_uuid', $room_uuid);
        $this->db->groupBy('bet_type');
        $bet_log = $this->db->get('bet_log', null, ['count(`bl_id`) as count', 'bet_type']);


        $lottery_info = [];
        foreach ($bet_log as $item => $value) {
            $lottery_info[$value['bet_type']] = $value['count'];

        }
        unset($bet_log);


        $data = [
            'type' => 'draw_coin',
            'area' => $param['area'],
            'from_uuid' => $from_uuid,
            'coin_type' => $param['coin_type'],
            'lottery_num' => $lottery_info
        ];

        TaskManager::async(new Broadcast(['type' => 'draw_coin', 'except_uuid' => $from_uuid, 'room_uuid' => $room_uuid, 'payload' => json_encode($data)]));


        //print_r($args);

    }

    public function update_online_users()
    {
        $room_uid = GameLogic::getRoomId($this->client()->getFd());
        $user_uuid = GameLogic::getUserFd($this->client()->getFd());
        $user_list = GameLogic::selectRoomUserId($room_uid);

        $cols = ['user_uuid,username,id,user_nick,headimg'];
        $this->db->where('user_uuid', ['in' => $user_list]);
        $users = $this->db->get('user', null, $cols);

        $data = ['type' => 'update_players', 'list' => $users];
        TaskManager::async(new Broadcast(['room_id' => $room_uid, 'payload' => json_encode($data)]));


    }


    public function getLastLotteryNumber($room_id = '', $round_id = '')
    {
        $this->db->where('room_uuid', $room_id);
        $this->db->orderBy('round_turn', 'desc');
        $r = $this->db->getOne('game_round', 'max(`round_turn`) as t ');
        $max_turn = $r['t'];

        $this->db->where('room_uuid', $room_id);
        $this->db->orderBy('round_turn', 'desc');
        $this->db->where('round_turn', $max_turn - 1);
        $s = $this->db->getOne('game_round');
        $number = $s['round_result'];

        $rs = MTool::handle_number($number);

        return $rs;

    }

    public function get_user_info()
    {
        $user_uuid = GameLogic::getUserId($this->client()->getFd());

        $room_id = GameLogic::getRoomId($this->client()->getFd());


        $cols = Array("id", "username", "user_nick", "coin", "headimg");
        $this->db->where('user_uuid', $user_uuid);
        $info = $this->db->getOne('user', $cols);
        $info['coin'] = MTool::formatNumber($info['coin']);

        // 计算输赢cishu

        $this->db->where('bet_result', 2);
        $this->db->where('user_id', $info['id']);
        $count = $this->db->getValue('bet_log', 'count(bl_id)');

        $this->db->where('bet_result', 1);
        $this->db->where('user_id', $info['id']);
        $win_count = $this->db->getValue('bet_log', 'count(bl_id)');
        $return_data = [
            'type' => 'update_user_info',
            'content' => ['own_info' => $info, 'game' => ['lose' => $count, 'win' => $win_count], 'last_lottery' => $this->getLastLotteryNumber($room_id)]
        ];
        $this->response()->write(json_encode($return_data));
    }

    public function welcome()
    {
        $param = $this->request()->getArgs();
        $client = $this->client();
        $data = $param['content'];
        $room_uid = $data['room_id'];


//        GameLogic::bindUser($user_uuid, $client->getFd());


        $user_list = GameLogic::selectRoomUserId($room_uid);
        $users = [];
        if (!empty($user_list)) {
            $cols = ['user_uuid,username,id,user_nick,headimg'];
            $this->db->where('user_uuid', ['in' => $user_list]);
            $users = $this->db->get('user', null, $cols);

        }

        $data = ['type' => 'update_players', 'list' => $users];

        $return_data = $data;

        $this->response()->write(json_encode($return_data));

    }


    public function ping()
    {
        return 'pong';
    }

    protected function getCurrentRoundInfo()
    {
        $current_time = time();
        $round_cache = Cache::getInstance()->get('round_cache');
        $result = $round_cache['round_list'];
        $current_round_id = 0;
        $round_curr_info = [];
        if (!empty($result)) {
            foreach ($result as $item => $value) {
                if ($current_time >= $value['start_time'] && $current_time < $value['stop_time']) {
                    $current_round_id = $value['round_id'];
                    $round_curr_info = $value;
                    break;
                }
            }

            return ['round_id' => $current_round_id, 'round_info' => $round_curr_info, 'round_period' => $round_cache['game_period']];

        }
        return false;
    }

    public function actionNotFound(?string $actionName)
    {
        $error_data = json_encode([
            'code' => '404',
            'msg' => 'action call ' . $actionName . ' not found',
            'content' => [],
        ]);
        $this->response()->write($error_data);
    }

}
